#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：api_automation_test 
@File    ：base_requests.py
@IDE     ：PyCharm 
@Author  ：XiaoDengYa
@Date    ：2021/7/21/021 16:29 
"""

import requests

from common.tools import allure_step, allure_title, logger, allure_step_no
from common.tools.data_process import DataProcess


class BaseRequest(object):
    session = None

    @classmethod
    def get_session(cls):
        """
        单例模式保证测试过程中使用的都是一个session对象
        :return:
        """
        if cls.session is None:
            cls.session = requests.Session()
        return cls.session

    @classmethod
    def send_request(cls, case: list) -> object:
        """处理case数据，转换成可用数据发送请求
        :param case: 读取出来的每一行用例内容，可进行解包
        return: 响应结果， 预期结果
        """
        # 编号、用例标题、请求头、ENV环境、header名称、接口地址、请求方式、入参关键、上传文件、请求数据、提取参数、后置SQL、预期结果
        case_number, case_title, header, env, header_name, path, method, parametric_key, file_obj, data, extra, sql, expect = case
        logger.info('[ 接口路径 ] : {}'.format(path))
        logger.info('[ 请求参数 ] : {}'.format(data))
        logger.info('[ 提取参数 ] : {}'.format(extra))
        logger.info('[ 后置SQL ] : {}'.format(sql))
        logger.info('[ 预期结果 ] : {}'.format(expect))
        # allure报告 用例标题
        allure_title(case_title)
        # 处理url、header、data、file、的前置方法
        url = DataProcess.handle_path(path, env)
        header = DataProcess.handle_header(header, header_name)
        data = DataProcess.handle_data(data)
        allure_step('请求参数', str(data))
        file = DataProcess.handler_files(file_obj)
        # 发送请求
        response = cls.send_api(url, method, parametric_key, header, data, file)
        if not response == "":
            # 提取参数
            DataProcess.handle_extra(extra, response)
            return response, expect, sql

    @classmethod
    def send_api(
            cls,
            url,
            method,
            parametric_key,
            header=None,
            data=None,
            file=None) -> str:
        """
        :param method: 请求方法
        :param url: 请求url
        :param parametric_key: 入参关键字， params(查询参数类型，明文传输，一般在url?参数名=参数值), data(一般用于form表单类型参数)
        json(一般用于json类型请求参数)
        :param data: 参数数据，默认等于None
        :param file: 文件对象
        :param header: 请求头
        :return: 返回res对象
        """
        session = cls.get_session()

        if parametric_key == 'params':
            res = session.request(
                method=method,
                url=url,
                params=data,
                headers=header)
        elif parametric_key == 'data':
            res = session.request(
                method=method,
                url=url,
                data=data,
                files=file,
                headers=header)
        elif parametric_key == 'json':
            res = session.request(
                method=method,
                url=url,
                json=data,
                files=file,
                headers=header)
        else:
            raise ValueError(
                '可选关键字为params, json, data')

        response = res.json()
        logger.info("-" * 100)
        logger.info('[ request url ] : {}'.format(res.url))
        logger.info('[ headers     ] : {}'.format(header))
        logger.info('[ cookies     ] : {}'.format(requests.utils.dict_from_cookiejar(res.cookies)))
        logger.info('[ method      ] : {}'.format(method.upper()))
        logger.info('[ data        ] : {}'.format(data))
        logger.info('[ response    ] : {}'.format(response))
        logger.info('[ time total  ] : {} s'.format(res.elapsed.total_seconds()))
        allure_step_no(f'响应耗时(s): {res.elapsed.total_seconds()}')
        allure_step('响应结果', response)
        return res.json()
